home *** CD-ROM | disk | FTP | other *** search
/ Die Ultimative Software-P…i Collection 1996 & 1997 / Die Ultimative Software-Pakete CD-ROM fur Atari Collection 1996 & 1997.iso / m / mailbox / mystery / applic / app.c next >
Encoding:
C/C++ Source or Header  |  1996-09-18  |  35.8 KB  |  1,243 lines

  1. /****************************************************************************
  2. '
  3. '               Header fuer Mystery-Applikationen unter MEGAMAX-C
  4. '                          Copyright PARROT-BERLIN
  5. '
  6. '
  7. ' Dieser Header stellt I/O-Routinen für MEGAMAX-C, sowie einige Systemvari-
  8. ' ablen von Mystery-Systems zur Verfügung.
  9. ' Es sind ausschließlich die angebotenen I/O-Routinen zu verwenden, die
  10. ' RS232C-Schnittstelle darf nicht umkonfiguriert werden.
  11. '
  12. ' Die angebotenen I/O-Routinen zeichnen sich dadurch aus, dass sie auf Kon-
  13. ' trollcodes, Carrierverlust, Timeout und Ueberschreiten der maximalen Benut-
  14. ' zerzeit reagieren und per longjmp Stellen im Programm anspringen, die vor-
  15. ' her mit setjmp markiert wurden. Generell lassen sich vier Typen von Events
  16. ' unterscheiden, fuer die zwei Environmentbuffer angelegt wurden (Termina-
  17. ' te_env und Break_env).
  18. '                                                       
  19. ' Benutzung der Jump-buffer                            
  20. '                                                       
  21. ' Event        abfragende Routinen      Buffer         
  22. '                                                       
  23. ' Carrier_lost Mbputchar/Mbgetchar      Terminate_env    
  24. ' t>tmax       Mbputchar                Terminate_env   
  25. ' timeout      Mbgetchar                Terminate_env   
  26. ' CTRL-X       ctrl                     Break_env       
  27. '                                                       
  28. '
  29. ' Prinzipiell muessen die Environmentbuffer vor der Benutzung von I/O-Routi-
  30. ' nen korrekt gesetzt sein, da es sonst zu Abstuerzen kommt. Damit die ganze
  31. ' Angelegenheit nicht unnoetig kompliziert wird, wird empfohlen, nur
  32. ' Break_env zu veraendern, damit das Programm auf CTRL_X reagiert.
  33. '
  34. ' Die Routinen sind weitgehend den Standardroutinen von C nachempfunden, als
  35. ' weitere Parameter werden jedoch haeufig BRK, NBRK und NCTRL verwendet. Die-
  36. ' se Parameter legen fest, ob die Ausgabe abgebrochen werden kann oder nicht.
  37. ' NCTRL wirkt dabei wie NBRK mit der zusaetzlichen Eigenschaft, dass RS232C
  38. ' generell nicht auf Kontrollcodes abgefragt wird.
  39. '
  40. ' Als weitere Besonderheit soll noch erwaehnt werden, dass die MORE- und die
  41. ' Slow-Option beim Programmstart von Mystery-Systems uebernommen werden,
  42. ' weiterhin weist Mbgets den Inline-Editor von Mystery-Systems auf.
  43.  
  44. ' Die compilierten Programme müssen die Extension .APP haben!!
  45. '
  46. '
  47. ' Sofern die folgenden Funktionen nicht ausreichend sein sollten oder
  48. ' Unklarheiten bestehen, bitte die PARROT unter (030) 724467 anrufen und
  49. ' eine PM an den Syop senden, bzw. eine Nachricht ins Visitors.brd setzen.
  50. '
  51. ' ACHTUNG: DIE ROUTINEN DIESES FILES SIND NICHT PUBLIC-DOMAIN, SIE DUERFEN
  52. '          ABER NICHTKOMMERZIELL VERWERTET WERDEN.
  53. '
  54. '
  55. '            Mit freundlichen Gruessen
  56. '
  57. '                     Horst
  58. '
  59. '
  60. '
  61. '***************************************************************************/
  62.  
  63. #include <osbind.h>
  64. #include <define.h>
  65. #include <string.h>
  66. #include <stdio.h>
  67. #include <errno.h>
  68. #include <ctype.h>
  69.  
  70.  
  71. /****************************************************************************
  72.  
  73.           Defines und Strukturen
  74.           
  75. ****************************************************************************/
  76.  
  77. #define   AUX             1
  78. #define   CON             2
  79.  
  80. #define   DEL          0x7F        /* Deletecodes f. verschiedene Computer */
  81. #define   BS              8
  82.  
  83. #define   CTRL_E          5
  84. #define   BEL             7
  85. #define   CR             13
  86. #define   CTRL_S         19
  87. #define   UP_ARROW       22       
  88. #define   DOWN_ARROW     23    
  89. #define   CTRL_X         24
  90. #define   RIGHT_ARROW    25
  91. #define   LEFT_ARROW     26
  92. #define   ESC            27 
  93.  
  94. #define   F1             59L       /* Scancodes */ 
  95. #define   F2             60L
  96. #define   F3             61L
  97. #define   F4             62L
  98. #define   F5             63L
  99. #define   F6             64L
  100. #define   F7             65L
  101. #define   F8             66L
  102. #define   F9             67L
  103. #define   F10            68L
  104.  
  105.  
  106. #define   A_ae          132        /* Umlaute, Sonderzeichen */
  107. #define   A_oe          148        /* A=Atari, Am=Amiga, M=Mac, PC=PC, E=EASCII */
  108. #define   A_ue          129
  109. #define   A_AE          142
  110. #define   A_OE          153
  111. #define   A_UE          154
  112. #define   A_SZ          158
  113. #define   A_PA          0xDD
  114.  
  115. #define   PC_SZ         0xE1    /* Rest ist wie Atari */
  116.  
  117. #define   SCRNWIDTH      79
  118. #define   BACKSPACE       Mbprintf(NCTRL,"\b \b")
  119. #define   CRLF            Mbprintf(NCTRL,"\r\n")
  120. #define   BELL            Mbputchar('\007',NBRK)                                     /* leer ist, ausserdem WERDEN KEINE USERINPUTS GESCHLUCKT */
  121. #define   VT_LEFT         Rsout("\033[D")
  122. #define   VT_RIGHT        Rsout("\033[C")
  123. #define   VT_STORE        Rsout("\0337")
  124. #define   VT_REST         Rsout("\0338")
  125. #define   VT_INSERT       Rsout("\033[4h")
  126. #define   VT_OVER         Rsout("\033[4l")
  127. #define   VT_DEL          Rsout("\033[1P")
  128. #define   VT_DELEOL       Rsout("\033[K") 
  129.  
  130. #define SCRN(a) bios(3,2,ESC); bios(3,2,a)
  131.  
  132. #define CRSR_UP SCRN('A')
  133. #define CRSR_DOWN SCRN('B')
  134. #define CRSR_RT SCRN('C')
  135. #define CRSR_LT SCRN('D')
  136. #define CLRSCRN SCRN('E')
  137. #define HOME SCRN('H')
  138. #define DEL_EOP SCRN('J')
  139. #define DEL_EOL SCRN('K')
  140. #define INSRT_LIN SCRN('L')
  141. #define KILL_LIN SCRN('M')
  142. #define CRSR_OFF SCRN('f')
  143. #define CRSR_ON SCRN('e')
  144. #define DEL_BOS SCRN('d')
  145. #define STORE_CRSR SCRN('j')
  146. #define RESTORE_CRSR SCRN('k')
  147. #define DEL_LIN SCRN('l')
  148. #define DEL_BOL SCRN('o')
  149. #define REV_ON SCRN('p')
  150. #define REV_OFF SCRN('q')
  151. #define WRAP_ON SCRN('v')
  152. #define WRAP_OFF SCRN('w')
  153. #define BGD_WHITE SCRN('c'); bios(3,2,0x30);
  154. #define BGD_BLACK SCRN('c'); bios(3,2,0x31);
  155.  
  156. #define GOTO(x,y) SCRN('Y'); bios(3,2,y+32); bios(3,2,x+32)
  157.  
  158.  
  159. #define   NBRK            0
  160. #define   BRK             1
  161. #define   NCTRL           2
  162.  
  163.  
  164. typedef struct
  165. {
  166.      unsigned BATCHING: 1;         /* true, wenn Batchbetrieb */
  167.      unsigned NOENTRY: 1;          /* true, wenn kein access auf rootdirectory moeglich ist */
  168.      unsigned SYSOUT:  1;          /* true, wenn System logoff durchfuehrte */
  169.      unsigned CARRIER_LOST: 1;     /* true wenn carrier-lost */
  170.      unsigned TOUT: 1;             /* true wenn timeout */
  171.      unsigned TMAX: 1;             /* true wenn maxtime ueberschritten */
  172.      unsigned BELLOFF: 1;          /* true wenn belloff */
  173.      unsigned LOCAL: 1;            /* true wenn localbetrieb */
  174.      unsigned SLOW: 1;             /* true fuer langsame Ausgabe */
  175.      unsigned CAT: 1;              /* true, wenn Katalog geladen */
  176.      unsigned MORE: 1;             /* true fuer Anhalten bei Boards u. Mails */
  177.      unsigned DIROWNER: 1;         /* true, wenn User Owner des aktuellen Directories ist */
  178.      unsigned ERROR: 1;            /* bei true werden Fehler angezeigt */ 
  179.      unsigned LONG: 1;             /* true, wenn langer Catalog angezeigt werden soll */
  180.      unsigned UPDATE: 1;           /* true, wenn Catalog zurueckgeschrieben werden muss */
  181.      unsigned LOGOUT: 1;           /* true bei logout durch den user */
  182. } FLAG;
  183.  
  184. typedef struct
  185. {
  186.      unsigned KILL_MAIL: 1;        /* true, wenn Mail gelesen wurde und geloescht werden kann */
  187.      unsigned PRINTER: 1;          /* wenn true, erfolgen Ausgaben auch auf Printer */
  188.      unsigned OPTION: 1;           /* wenn true, Option zum Schreiben nach dem Lesen eines Boards */
  189.      unsigned EXPAND: 1;           /* wenn true, kein cr-lf vor und nach errors */
  190.      unsigned NO_ECHO: 1;          /* wenn true, einmalig kein Echo bei Mbgets */
  191.      unsigned HIDE: 1;             /* wenn true, Ausgabe erst ab 'logged in at... */
  192.      unsigned INTERPRET: 1;        /* ermoeglicht UP_ARROW und DOWN_ARROW */
  193.      unsigned INSERT: 1;           /* true, wenn Userterminal auf Insert geschaltet wurde */
  194.      unsigned EDITLINE: 1;         /* true, wenn Zeile im Editor editiert werden soll */
  195.      unsigned INFO: 1;             /* true, wenn bei Catalogen das Readdatum der Items ausgegeben werden soll */
  196.      unsigned NOSPOOL: 1;          /* gesetzt durch Option Nospool beim Einloggen->Read-zugriffe werden nicht registriert */
  197.      unsigned INFOLINE: 1;         /* wenn true, wird Infoline angezeigt */
  198. } FLAG2;
  199.   
  200. typedef struct 
  201. {
  202.      char NAME[21];
  203.      char CLASS[3];           
  204.      char GROUP[5];      
  205.      char DATE[9];
  206.      char TIME[9];
  207.      char CALLS[7]; 
  208. } USER;
  209.  
  210. typedef struct 
  211. {
  212.      char *IBUFF;
  213.      int IBUFSIZ;
  214.      int IBUFTL;
  215.      int IBUFHD;
  216.      int IBUFLOW;
  217.      int IBUFHI;
  218.      long *OBUFF;
  219.      int OBUFSIZ;
  220.      int OBUFTL;
  221.      int OBUFHD;
  222.      int OBUFLOW;
  223.      int OBUFHI;
  224. } RSIOREC;
  225.  
  226. typedef struct 
  227. {
  228.      unsigned sec:  5;
  229.      unsigned min:  6;
  230.      unsigned hour: 5;
  231. } ZEITFELD;
  232.  
  233. typedef struct 
  234. {
  235.      int SEKUNDEN;
  236.      int MINUTEN;
  237.      int STUNDEN;
  238. } UHRZEIT;
  239.  
  240. typedef struct
  241. {
  242.      FLAG    *APP_FLAG;        /* Pointer auf Systemflags1           */
  243.      FLAG2   *APP_FLAG2;       /* Pointer auf Systemflags2           */
  244.      USER    *APP_USER;        /* Pointer auf Userdaten              */ 
  245.      char    *APP_SYSPATH;     /* Pfad ins Systemdirectory           */
  246.      char    *APP_CATBUFF;     /* Pointer auf Catalogbuffer          */
  247.      long    *APP_CATCOUNT;    /* Länge des Catalogs                 */
  248.      long    APP_CALLS;        /* aktuelle Zahl der Anrufe           */
  249.      int     APP_TMAX;         /* maximale Benutzerzeit in min.      */
  250.      long    APP_LOGINTIME;    /* Einlogzeit in s (24:00=0s)         */
  251.      int     APP_BAUD;         /* aktuelle Baudrate                  */
  252.      int     APP_SCREENSIZE;   /* Screengroesse des Users in Zeilen  */ 
  253.      char    *APP_ICNVRT;      /* Pointer auf Inputwandlungstabelle  */
  254.      char    *APP_OCNVRT;      /* Pointer auf Outputwandlungstabelle */
  255. } APP_PAR;
  256.  
  257. extern long atol();
  258.  
  259. /****************************************************************************
  260.  
  261.         Fuer den Programmierer der Applikation interessante Variablen
  262.            
  263. ****************************************************************************/
  264.  
  265. FLAG  *Flag;                   /* Pointer auf Mystery Flags         */
  266. FLAG2 *Flag2;                  /* Pointer auf Mystery Flag2         */
  267. USER  *User;                   /* Pointer auf Userstruktur          */
  268. long Calls;                    /* Anzahl der Anrufer                */
  269. long Time;                     /* Zwischenspeicher fuer Zeiten in s */
  270. int  Touttime=60;              /* Zeit fuer Timeout in s            */
  271. int  Tmax;                     /* aktuelle maximale Benutzerzeit    */
  272. long Login_time;               /* Einlogzeit des Users in Sekunden  */
  273. int Cr_count;                  /* Zeilenzaehler fuer MORE           */ 
  274. jmp_buf Terminate_env;         /* fuehrt normalerweise nach exit    */
  275. jmp_buf Break_env;             /* muss vor I/O definiert werden     */
  276. int Screensize;                /* Groesse (Zeilen) des Userscreens  */
  277. char *Convert_oarray;          /* Zeiger auf Outputwandlungstabelle */
  278. char *Convert_iarray;          /* Zeiger auf Inputwandlungstabelle  */
  279.  
  280. /****************************************************************************
  281.  
  282. *****************************************************************************
  283.  
  284.                          some stuff
  285.                          
  286. ****************************************************************************/
  287.  
  288. char *Rsbuff;
  289. int Last_char=0;
  290. long *hz_200 = (long *) 0x000004ba;
  291.  
  292. UHRZEIT Uhrzeit;
  293.  
  294.  
  295. int Last_input;                /* gespeichert durch ctrl bei NBRK */
  296.  
  297. RSIOREC *new_rsiorec;
  298.  
  299. short int *MFP = 0xFFFA01;
  300.  
  301. APP_PAR *App_par;   /* bekommen wir als erstes Argument uebergeben */
  302.  
  303. long Ti()                          /* Uhrzeit in Sekunden   */
  304. {
  305.      long time;
  306.  
  307.      Zeit();
  308.      time = Uhrzeit.STUNDEN * 3600L + Uhrzeit.MINUTEN * 60L + (long)Uhrzeit.SEKUNDEN;
  309.      return(time);
  310. }
  311.  
  312. Carrier()                /* prueft auf CARRIER */
  313. {
  314.      short int  n;         
  315.      long save_ssp;
  316.  
  317.      save_ssp = Super(0L);
  318.      n = *MFP;
  319.      Super(save_ssp);
  320.      n = !((n & 2) >> 1);        
  321.      return(n);                 /* n=true if carrier */                        
  322. }
  323.  
  324.  
  325. /***************************************************************************/
  326. /*                                                                         */
  327. /* Erlaeuterungen zu I/O und Longjumps                                     */
  328. /*                                                                         */
  329. /* Terminate_env muss vor allen I/O-Operationen korrekt gesetzt sein.      */
  330. /*                                                                         */
  331. /* Break_env muss vor allen Ausgabeoperationen gesetzt sein, bei denen     */
  332. /* BRK erlaubt ist.                                                        */
  333. /*                                                                         */
  334. /*                                                                         */
  335. /*                                                                         */
  336. /***************************************************************************/
  337.  
  338.  
  339. Sterminal()     /* 0 oder Zeichen von RS232C                */
  340.                 /* wenn !Carrier(), dann wird kein Zeichen  */
  341. {               /* angenommen                               */
  342.      int c=0;
  343.                            
  344.      if(Bconstat(AUX)&&Carrier())                           
  345.           c = Bconin(AUX);
  346.           
  347.      return(c);
  348. }
  349.  
  350. Terminal()           /* Holt Zeichen von der Console */
  351. {
  352.      long c=0;
  353.      int scancode;
  354.      
  355.      if(Bconstat(CON))
  356.      {
  357.           c=Bconin(CON);
  358.           scancode=c>>16;
  359.       
  360.           if(scancode>71 && scancode<81)
  361.           {
  362.                switch(scancode)
  363.                {
  364.                
  365.                     case 75:  c=LEFT_ARROW;
  366.                               break;
  367.                               
  368.                     case 77:  c=RIGHT_ARROW;
  369.                               break;
  370.                               
  371.                     default:  c=0;
  372.                               break;          
  373.                }
  374.                
  375.           }
  376.                                         
  377.      }
  378.      
  379.      return((int)c);
  380. }
  381.  
  382. /****************************************************************************
  383.  
  384.  
  385.           Vom Programmierer der Applikation zu benutzende I/O-Routinen
  386.  
  387.  
  388. ****************************************************************************/
  389.  
  390.  
  391. Mbgetchar()         /* wartet auf Eingabe von RS232C oder Tastatur   */
  392. {                   /* Exit mit char oder CR und Flag.TOUT=1 bei     */
  393.                     /* Timeout oder Flag.CARRIER_LOST=1 bei Carrier- */
  394.                     /* verlust */
  395.                     
  396.      int c; 
  397.      Time = Ti();
  398.  
  399.      Last_char=0;
  400.  
  401.      do
  402.      {
  403.          if(!(c=con_legal(Terminal())))
  404.                c=legal(Sterminal()); 
  405.           
  406.           if(Tout() || Carrier_lost())
  407.                longjmp(Terminate_env,0);       /* Session beenden */            
  408.      }
  409.      while(!c);
  410.  
  411.      return(c);
  412. }
  413.  
  414. Mbputchar(c,mode)        /* Ausgabe auf Schirm und RS232C */
  415. char c;
  416. int mode;                         
  417. {
  418.      char in, auxout1, auxout2, conout1, conout2;
  419.  
  420.      if(Flag->LOCAL)
  421.           conout1=Convert_oarray[2*(unsigned)c];
  422.           
  423.      else
  424.      {
  425.           auxout1=Convert_oarray[2*(unsigned)c];
  426.           auxout2=Convert_oarray[2*(unsigned)c+1];
  427.           conout1=c;
  428.      }
  429.           
  430.      if((Carrier_lost() || Maxtime_exceeded()) && mode==BRK)
  431.      {
  432.           CRLF;
  433.           longjmp(Terminate_env,0);
  434.      }
  435.       
  436.      if(conout1=='\n')
  437.      {
  438.           Cr_count++;
  439.           Bconout(CON,conout1);
  440.      }
  441.                
  442.      else
  443.      {
  444.           if(conout1 != ESC)
  445.                Bconout(CON,conout1);
  446.      }
  447.      
  448.      if(Carrier())
  449.      {
  450.           Bconout(AUX,auxout1);
  451.  
  452.  
  453.           if(auxout2 && Carrier())
  454.                Bconout(AUX,auxout2);          
  455.      }
  456.      
  457.      if(Flag->MORE && conout1=='\n')
  458.      {
  459.           if(Cr_count>(Screensize-1))
  460.           {
  461.                Cr_count=1;
  462.                Mbprintf(NBRK,"<===MORE===>");
  463.                in=More_getchar();
  464.               
  465.                Mbprintf(NBRK,"\r            \r");
  466.                
  467.                if((in==CTRL_X || in=='q') && mode==BRK)
  468.                     longjmp(Break_env,0);
  469.                
  470.                if(in==CTRL_E || in=='Q')
  471.                     longjmp(Terminate_env,0);
  472.           }
  473.      }
  474. }
  475.  
  476. /* wie printf, jedoch ueber Screen und RS232C. Max. 10 Parameter! */
  477. /* mode (BRK, NBRK, NCTRL) bestimmt, ob abgebrochen werden kann.  */            
  478.  
  479. Mbprintf(mode,pointer,p0,p1,p2,p3,p4,p5,p6,p7,p8,p9)
  480. int mode;
  481. char *pointer,*p0,*p1,*p2,*p3,*p4,*p5,*p6,*p7,*p8,*p9;
  482. {
  483.      char puffer[161];
  484.  
  485.      sprintf(puffer,pointer,p0,p1,p2,p3,p4,p5,p6,p7,p8,p9);
  486.      mbtype((long) strlen(puffer),puffer,mode);
  487. }
  488.  
  489. Mbgets(line,count)  /* Routine holt count Zeichen von der Con- */
  490. char *line;         /* sole oder RS232C                        */
  491. int count;
  492. {
  493.      unsigned char inp; 
  494.      char buffer[160];
  495.      int i=0;
  496.      int crsr=0;
  497.  
  498.      if(Flag2->EDITLINE)
  499.      {
  500.           i=crsr=strlen(line);
  501.           
  502.           Mbprintf(NBRK,"\r\n%s",line);
  503.           
  504.           if(i==count)
  505.           {
  506.                CRSR_LT;
  507.                VT_LEFT;
  508.                crsr--;
  509.           }
  510.           
  511.           else
  512.                Flag2->EDITLINE=0;     
  513.      }
  514.  
  515.      else
  516.           line[0]='\0';
  517.   
  518.                
  519.      while (i < (count+Flag2->EDITLINE)) 
  520.      {
  521.           inp=Mbgetchar();
  522.     
  523.           if(is_controll(inp))
  524.                handle_ctrl(inp,&crsr,&i,line);
  525.           
  526.           else 
  527.           {
  528.                if (inp == '\r') 
  529.                     break;
  530.             
  531.                if(i==crsr)
  532.                {
  533.                     line[i++] = inp; line[i] = '\0';
  534.                     Mbputchar(inp,BRK);
  535.                     crsr++;
  536.                }
  537.                
  538.                else
  539.                {
  540.                     if(!Flag2->EDITLINE)
  541.                     {
  542.                          l_insert(inp,line+crsr);
  543.                          crsr++;
  544.                          i++;
  545.                     }     
  546.                }   
  547.           }
  548.      }
  549.      
  550.      if(Flag2->INSERT)
  551.      {
  552.           VT_OVER;
  553.           Flag2->INSERT=0;
  554.      }     
  555.           
  556.      Cr_count=0;     
  557.      CRLF;
  558.  
  559. }
  560.  
  561. /* wie scanf, jedoch ueber Screen und RS232C. Max. 10 Parameter! */
  562. /* maximale Stringlaenge muss vorgegeben werden                  */
  563.  
  564. Mbscanf(count,format,p0,p1,p2,p3,p4,p5,p6,p7,p8,p9)
  565. int count;
  566. char *format,*p0,*p1,*p2,*p3,*p4,*p5,*p6,*p7,*p8,*p9;
  567.  
  568. {
  569.      char puffer[180];
  570.  
  571.      Mbgets(puffer,count);
  572.      strcat(puffer," @ @ @ @ @ @ @ @ @ @ ");  /* das ist hier noetig!! */            
  573.      sscanf(puffer,format,p0,p1,p2,p3,p4,p5,p6,p7,p8,p9);
  574. }
  575.  
  576. Mbputfile(source)   /* gibt geoeffnetes File aus */
  577. FILE *source;
  578. {         
  579.      char c;
  580.      jmp_buf breakstore;
  581.      
  582.      Save_env(Break_env,breakstore); /* Environment saven */
  583.      
  584.      if(!setjmp(Break_env))
  585.      {
  586.           while((c = getc(source)) !=EOF)
  587.           {
  588.                charout(c,BRK);
  589.                ctrl(BRK);
  590.           }
  591.      }
  592.      
  593.      fclose(source);
  594.      
  595.      Save_env(breakstore,Break_env); /* Environment wieder herstellen */
  596. }
  597.  
  598. /****************************************************************************
  599.  
  600.      Andere Routinen, die nuetzlich sein koennten
  601.      
  602. ****************************************************************************/
  603.  
  604. Empty_rsbuf()  /* loescht RS232C-Eingabepuffer */
  605. {
  606.      new_rsiorec->IBUFHD = new_rsiorec->IBUFTL = 0;
  607. }
  608.  
  609. Elapsed_time()      /* returns die seit dem Einloggen verstrichene Zeit in Minuten */
  610. {
  611.      long zeit;
  612.  
  613.      zeit=Ti()-Login_time;
  614.  
  615.      if(zeit<0)
  616.           zeit += 86400;
  617.  
  618.      return((int)(zeit/60));
  619. }
  620.  
  621. Change(pointer) /* setzt String in Grossbuchstaben um */
  622. char *pointer;
  623. {
  624.      while(*pointer)
  625.           *pointer++=toupper(*pointer);
  626. }
  627.  
  628. /****************************************************************************
  629.  
  630.                stuff cont.
  631.                
  632. ****************************************************************************/
  633.  
  634. legal(c)  /*  Ueberprueft Eingaben des Users auf Legalitaet */
  635. int c;    /*  und wandelt ggf auch Deletecodes um */
  636.  
  637. {
  638.      int back;
  639.      static int store;
  640.      
  641.      if(!c)
  642.           return(FALSE);
  643.    
  644.      if(store=='[')
  645.      {
  646.           switch(c)
  647.           {
  648.                case 'A':      store=0;
  649.                               return(UP_ARROW);
  650.                               break;
  651.                               
  652.                case 'B':      store=0;
  653.                               return(DOWN_ARROW);
  654.                               break;
  655.                               
  656.                case 'C':      store=0;
  657.                               return(RIGHT_ARROW);
  658.                               break;
  659.                               
  660.                case 'D':      store=0;
  661.                               return(LEFT_ARROW);
  662.                               break;
  663.                               
  664.                default:       if(c!='1')
  665.                                    store=0;
  666.                               
  667.                               else
  668.                                    return(FALSE);
  669.           }                          
  670.      
  671.      }
  672.  
  673.      if(store==ESC)
  674.      {
  675.           if(c == '[')
  676.           {     
  677.                store=c;
  678.                return(FALSE);
  679.           }
  680.           
  681.           else
  682.                store=0;
  683.      }
  684.      
  685.      if(c==CTRL_S)
  686.           Time=Ti();
  687.  
  688.      if(c==ESC)
  689.           store=ESC;
  690.  
  691.      back=(unsigned)Convert_iarray[c];
  692.    
  693.        
  694.      return(back);
  695. }
  696.  
  697. con_legal(c)  /*  Ueberprueft Eingaben von der Console auf Legalitaet */
  698. int c;        /*  und wandelt ggf auch Deletecodes um */
  699. {
  700.      int back;
  701.      
  702.      switch(c)
  703.      {
  704.           case CTRL_S:   Time=Ti();
  705.                          back=0;
  706.                          break;
  707.           case DEL:
  708.           case BS:
  709.           case CR:               
  710.           case UP_ARROW:
  711.           case DOWN_ARROW:
  712.           case LEFT_ARROW:
  713.           case RIGHT_ARROW:   
  714.           case A_ae:
  715.           case A_oe:
  716.           case A_ue:
  717.           case A_AE:
  718.           case A_OE:
  719.           case A_UE:
  720.           case A_PA:
  721.           case A_SZ:     back=c;
  722.                          break;
  723.                                
  724.           default:       back=(c<32 || c>126) ? 0 : c;
  725.                      
  726.      }
  727.      
  728.      return(back);
  729. }
  730.  
  731. More_getchar()      /* eigenes getchar fuer more, weil sonst ctrl-x nicht beruecksichtigt wird */  
  732. {                  
  733.      int c, store; 
  734.      Time = Ti();
  735.  
  736.      store=Touttime;
  737.      Touttime=300;
  738.      
  739.      do
  740.      {
  741.        if(!(c=Terminal()))
  742.           c=Sterminal();
  743.           
  744.        c=more_legal(c);   
  745.           
  746.        if(Carrier_lost())
  747.           longjmp(Terminate_env,0);       /* Session beenden */
  748.           
  749.        if(Maxtime_exceeded())
  750.           longjmp(Terminate_env,0);       /* Session beenden */
  751.           
  752.        if(Tout())
  753.           longjmp(Terminate_env,0);
  754.      }
  755.      while(!c);
  756.  
  757.      Touttime=store;
  758.      
  759.      return(c);
  760. }
  761.  
  762. more_legal(c)  /*  Ueberprueft Eingaben auf Legalitaet */
  763. int c;  
  764.  
  765. {
  766.      int back;
  767.      
  768.      return(back=((c<32 || c>126) && c!=CTRL_X && c!=CR) ? 0 : c);
  769. }
  770.  
  771. Rsout(string) /* Ausgabe nur ueber Rs323c */
  772. char *string;
  773. {
  774.      while(*string)
  775.      {
  776.           if(Carrier())
  777.                Bconout(AUX,*string);
  778.  
  779.           string++;
  780.      }          
  781. }
  782.  
  783.  
  784. charout(c,mode)          /* Ausgabe fuer Mailbox */
  785. char c;
  786. int mode;
  787. {
  788.      while(new_rsiorec->OBUFHD != new_rsiorec->OBUFTL);
  789.  
  790.      Mbputchar(c,mode);
  791.  
  792.      if(Flag->SLOW)
  793.           Wait(30L);
  794. }
  795.  
  796.  
  797. ctrl(mode)         /* stellt fest, welcher code, wartet bei CTRL_S */
  798. int mode;
  799. {
  800.      register int c;
  801.      
  802.      if(mode==NCTRL)
  803.           return;
  804.  
  805.      if(!(c=Last_char))               
  806.           if(!(c=Terminal()))
  807.                if(!(c=Sterminal()))
  808.                     return;
  809.           
  810.      Last_char=0;
  811.                
  812.      if(c==CTRL_S)
  813.      {
  814.           c=halt(mode);
  815.      }
  816.      
  817.      Empty_rsbuf();
  818.      
  819.      if(mode!=NBRK && c==CTRL_X)
  820.      {     
  821.           Cr_count=0;
  822.           CRLF;
  823.           longjmp(Break_env,0);
  824.      }
  825.     
  826.      else
  827.           Last_char=c; 
  828. }    
  829.           
  830. halt(mode)    /* wartet auf naechstes Zeichen des Users */
  831. int mode;
  832. {
  833.      int c;
  834.      
  835.      Time=Ti();
  836.      
  837.      Cr_count=0;
  838.  
  839.      do
  840.      {
  841.           if(!(c=Terminal()))
  842.                c=Sterminal();
  843.                
  844.           if(c==CTRL_S)
  845.                c=0;
  846.                
  847.      }
  848.      while(!Tout() && !Carrier_lost() && !c);
  849.           
  850.      Flag->TOUT=0;
  851.      return(c);
  852. }          
  853.  
  854. mbtype(count,buff,mode)  /* gibt Daten ueber Screen und RS232C aus */
  855. register long count;   
  856. register char *buff;
  857. int mode;             
  858. {
  859.  
  860.      long counter=0;
  861.  
  862.      while(counter < count)
  863.      {
  864.           charout(*buff,mode);
  865.           ctrl(mode);
  866.           counter++;
  867.           buff++;
  868.      }
  869. }
  870.  
  871. Mbwrite(count,buff) /* wie Write, jedoch ueber Screen und RS232C */
  872. long count;
  873. char *buff;
  874. {
  875.      mbtype(count,buff,BRK);
  876. }
  877.  
  878.  
  879. handle_ctrl(input,crsr,end,buffer)
  880. int input,*crsr,*end;
  881. char *buffer;
  882. {
  883.      int back=TRUE;
  884.      int i;
  885.     
  886.      switch(input)
  887.      {
  888.           case BS:            if(*crsr>0)
  889.                               {
  890.                                    if(*end == *crsr)
  891.                                    {
  892.                                         buffer[--(*end)]= '\0';
  893.                                         (*crsr)--;
  894.                                         BACKSPACE;
  895.                                    }
  896.                                    
  897.                                    else
  898.                                    {
  899.                                         backdelete(buffer+(*crsr)--);
  900.                                         (*end)--;
  901.                                    }
  902.                               }
  903.                               
  904.                               else
  905.                               {
  906.                                    if(!Flag->BELLOFF)
  907.                                         BELL;
  908.                               }
  909.                               
  910.                               break;
  911.                      
  912.           case DEL:           if(*end>0)
  913.                               {
  914.                                    if(*end == *crsr)
  915.                                    {
  916.                                         buffer[(*end)--]='\0';
  917.                                         (*crsr)--;
  918.                                         BACKSPACE;
  919.                                    }
  920.                                    
  921.                                    else
  922.                                    {
  923.                                         l_delete(buffer+(*crsr));
  924.                                         (*end)--;
  925.                                         
  926.                                         if(*end == *crsr)
  927.                                         {
  928.                                              Flag2->INSERT=0;
  929.                                              VT_OVER;
  930.                                         }     
  931.                                    }
  932.  
  933.                                }
  934.                                
  935.                                else
  936.                                {
  937.                                    if(!Flag->BELLOFF)
  938.                                         BELL;
  939.                                }
  940.                               
  941.                                break;
  942.                                                                           
  943.           case LEFT_ARROW:     if(*crsr>0)
  944.                                {
  945.                                    CRSR_LT;
  946.                                    VT_LEFT;
  947.                                    (*crsr)--;
  948.  
  949.                                    if(!Flag2->INSERT)
  950.                                    {
  951.                                         Flag2->INSERT=1;
  952.                                         VT_INSERT;
  953.                                    }     
  954.                                }
  955.                                         
  956.                                else
  957.                                {
  958.                                    if(!Flag->BELLOFF)
  959.                                         BELL;
  960.                                }
  961.                               
  962.                                break;
  963.                                         
  964.           case RIGHT_ARROW:    if(*crsr < *end)
  965.                                {
  966.                                    CRSR_RT;
  967.                                    VT_RIGHT;
  968.                                    (*crsr)++;
  969.                                    
  970.                                    if(*crsr == *end)
  971.                                    {
  972.                                         Flag2->INSERT=0;
  973.                                         VT_OVER;
  974.                                    }     
  975.                                }
  976.                                         
  977.                                break;
  978.                                         
  979.      }                                        
  980.  
  981.      return(back);
  982.  
  983.  
  984. backdelete(pointer)
  985. char *pointer;
  986. {
  987.      Flag2->EDITLINE=0;
  988.      VT_LEFT;
  989.      CRSR_LT;
  990.      STORE_CRSR;
  991.      CRSR_OFF;
  992.      VT_DEL;
  993.      strcpy(pointer-1,pointer);
  994.      printf("%s ",pointer-1);
  995.      fflush(stdout);
  996.      RESTORE_CRSR;
  997.      CRSR_ON;
  998. }
  999.  
  1000. l_delete(pointer)
  1001. char *pointer;
  1002. {
  1003.      Flag2->EDITLINE=0;
  1004.      STORE_CRSR;
  1005.      CRSR_OFF;
  1006.      VT_DEL;
  1007.      strcpy(pointer,pointer+1);
  1008.      printf("%s ",pointer);
  1009.      fflush(stdout);
  1010.      RESTORE_CRSR;
  1011.      CRSR_ON;
  1012. }                                                    
  1013.  
  1014. l_insert(inp,pointer)
  1015. char *pointer;
  1016. int inp;
  1017. {
  1018.      char buffer[190];
  1019.  
  1020.      strcpy(buffer,pointer);
  1021.      *pointer= inp;
  1022.      *(pointer+1)= '\0';
  1023.  
  1024.      Mbputchar(inp,BRK);
  1025.      STORE_CRSR;
  1026.      CRSR_OFF;
  1027.      printf("%s",buffer);
  1028.      fflush(stdout);
  1029.      RESTORE_CRSR;
  1030.      CRSR_ON;
  1031.      strcat(pointer,buffer);
  1032. }
  1033.   
  1034.  
  1035. is_controll(c)
  1036. int c;
  1037. {
  1038.      return(c==BS || c==DEL || c==LEFT_ARROW || c==RIGHT_ARROW);
  1039. }
  1040.  
  1041.  
  1042. Maxtime_exceeded()       /* returns true, if maxtime exceeded    */
  1043. {
  1044.      if(Elapsed_time() < Tmax)
  1045.           return(FALSE);
  1046.  
  1047.      Flag->TMAX=1;
  1048.      return(TRUE);
  1049. }
  1050.  
  1051. long Fetch_ticks()  /* holt ticks aus 200hz-Counter */
  1052. {
  1053.      long save_ssp,ticks;
  1054.      
  1055.      save_ssp=Super(0L);
  1056.      ticks=*hz_200;
  1057.      Super(save_ssp);
  1058.      
  1059.      return(ticks);
  1060. }
  1061.      
  1062. Wait(n)                     /* wartet n millisekunden (kleinste Aufloesung 5 ms) */
  1063. long n;
  1064. {
  1065.      long startticks, ticks, sollticks;
  1066.      
  1067.      sollticks = n/5;              /* ein tick = 5ms */
  1068.      startticks = Fetch_ticks();    
  1069.  
  1070.      for(;;)
  1071.      {
  1072.      
  1073.           ticks=Fetch_ticks()-startticks;
  1074.           
  1075.           if(ticks<0)
  1076.                ticks+=0xEFFFFFFFL;
  1077.                
  1078.           if(ticks>=sollticks)
  1079.                break;
  1080.      }     
  1081. }
  1082.  
  1083.  
  1084. Save_env(source,dest) /* speichert Environment in dest */
  1085. jmp_buf source, dest;
  1086. {
  1087.      int x;
  1088.      
  1089.      for(x=0;x<9;x++)
  1090.           dest[x]=source[x];
  1091. }
  1092.  
  1093. Zeit()
  1094. {
  1095.  
  1096.  
  1097.      int time;
  1098.      ZEITFELD *pointer;
  1099.      
  1100.      pointer=(ZEITFELD *)&time;
  1101.      
  1102.      time = Tgettime();
  1103.      Uhrzeit.STUNDEN = pointer->hour;
  1104.      Uhrzeit.MINUTEN = pointer->min;
  1105.      Uhrzeit.SEKUNDEN = pointer->sec * 2;
  1106. }
  1107.  
  1108. Carrier_lost()     /* True wenn weder Carrier noch Lokalbetrieb */
  1109. {
  1110.      int flag;
  1111.      flag = !Carrier() && !Flag->LOCAL;
  1112.      Flag->CARRIER_LOST = flag;
  1113.      return(flag);
  1114. }
  1115.  
  1116. Tout()                    /* True, wenn Timeout   */
  1117. {
  1118.      int flag = FALSE;
  1119.      long x;
  1120.  
  1121.      x = Ti() - Time;
  1122.    
  1123.      if(x < 0L)
  1124.           x += 86400;
  1125.           
  1126.      if(x > ((long) Touttime))
  1127.      {
  1128.           flag = TRUE;
  1129.           Flag->TOUT = TRUE;
  1130.      }
  1131.      
  1132.      return(flag);
  1133. }
  1134.  
  1135. prepare()        /* exit vorbereiten */
  1136. {
  1137.      Flag2->EDITLINE=0;
  1138.      Flag2->INSERT=0;
  1139.      VT_OVER;
  1140. }
  1141.  
  1142. /****************************************************************************
  1143.  
  1144.      Beginn von main mit ein paar Beispielen
  1145.      
  1146. ****************************************************************************/
  1147.  
  1148. main(argc,argv)     /* Start des Programms */
  1149. int argc;
  1150. char *argv[];
  1151. {
  1152.      char inputbuffer[21];
  1153.      
  1154.      if(argc==1)
  1155.           exit(1);                        /* ohne Argumente wollen wir nicht */
  1156.  
  1157.      App_par=(APP_PAR *)atol(argv[1]);    /* wir holen Variablen */
  1158.     
  1159.      Flag=(FLAG *)(App_par->APP_FLAG);
  1160.      Flag2=(FLAG2 *)(App_par->APP_FLAG2);
  1161.      User=(USER *)(App_par->APP_USER);
  1162.      Calls=App_par->APP_CALLS;
  1163.      Tmax=App_par->APP_TMAX;
  1164.      Login_time=App_par->APP_LOGINTIME;
  1165.      new_rsiorec = (RSIOREC *)Iorec(0);
  1166.      Convert_iarray=App_par->APP_ICNVRT;
  1167.      Convert_oarray=App_par->APP_OCNVRT;
  1168.      Screensize=App_par->APP_SCREENSIZE;          
  1169.  
  1170. /* Diese Stelle wird angesprungen bei Verlust des Carriers, Timeout
  1171.    oder Ueberschreiten der maximalen Benutzerzeit                        */
  1172.    
  1173.      if(setjmp(Terminate_env))
  1174.      {
  1175.           prepare();
  1176.           exit(1);
  1177.      }
  1178.           
  1179.      CRLF;          /* Leerzeilen nach Programmstart, Break_env braucht */
  1180.      CRLF;          /* noch nicht gesetzt zu werden. da CTRL_X nicht    */
  1181.                     /* moeglich ist */
  1182.                     /* bei Mbprintf fuer Zeilenvorschub immer \r\n ver  */
  1183.                     /* wenden !!                                        */
  1184.  
  1185.      Mbprintf(NBRK,"         TESTAPPLIKATION\r\n");
  1186.      Mbprintf(NBRK,"         ===============\r\n\r\n\r\n");      
  1187.      Mbprintf(NBRK,"Moechtest Du eine Anleitung (J/N)?>");
  1188.      Mbgets(inputbuffer,20); /* Antwort mit maximal 20 Zeichen holen */
  1189.      
  1190.      Empty_rsbuf(); /* sicherheitshalber Inputbuffer loeschen           */
  1191.      
  1192.      if(!setjmp(Break_env)) /* es folgen Ausgaben, die mit CTRL_X abge- */
  1193.      {                      /* brochen werden koennen, deswegen muss    */
  1194.                             /* Break_env gesetzt werden                 */
  1195.                             
  1196.           if(*inputbuffer=='J' || *inputbuffer=='j')
  1197.           {
  1198.                Mbprintf(BRK,"\r\nDas ist ein Beispiel fuer eine Gebrauchsanweisung, die natuerlich\r\n");
  1199.                Mbprintf(BRK,"hier nur einen totalen Unsinnstext bringt. Es wird aber gezeigt,\r\n");
  1200.                Mbprintf(BRK,"dass hier ein Text ausgegeben wird, der sich abbrechen laesst.\r\n");
  1201.           }
  1202.      }
  1203.      
  1204.      *inputbuffer='\0';
  1205.      
  1206.      while(strcmp(inputbuffer,"ENDE"))
  1207.      {     
  1208.           Mbprintf(NBRK,"\r\nWas nun %s (Spiel,Ende)?>",User->NAME);
  1209.           Mbgets(inputbuffer,20);
  1210.           Change(inputbuffer);       /* Antwort in Grossbuchstaben umsetzen */
  1211.           
  1212.           CRLF;
  1213.           
  1214.           if(!strcmp(inputbuffer,"SPIEL"))
  1215.                Mbprintf(NBRK,"Das waere das Spiel...\r\n");
  1216.                
  1217.           else
  1218.           {
  1219.                if(strcmp(inputbuffer,"ENDE"))
  1220.                     Mbprintf(NBRK,"Eingabefehler!!!\r\n");
  1221.           }
  1222.      }
  1223.      
  1224.      /* Spieler hat Ende gewaehlt, es kommt nun noch etwas Bla-bla, um zu */
  1225.      /* zu zeigen, dass vor jeder abbrechbaren Ausgabe Break_env gesetzt  */
  1226.      /* werden muss                                                       */
  1227.      
  1228.      if(!setjmp(Break_env))
  1229.      {
  1230.           Mbprintf(BRK,"Ich hoffe, Dir hat das Spiel gefallen %s und Du startest es bald mal\r\nwieder.\r\n\r\n",User->NAME);
  1231.           Mbprintf(BRK,"Statistik\r\n");
  1232.           Mbprintf(BRK,"=========\r\n\r\n");
  1233.           Mbprintf(BRK,"Zeit im System %d min.\r\n",Elapsed_time());
  1234.           Mbprintf(BRK,"Anrufer insgesamt %ld\r\n",Calls);
  1235.           Mbprintf(BRK,"Deine Anrufe bisher %ld\r\n\r\n",atol(User->CALLS));
  1236.      }
  1237.  
  1238.      prepare();                        
  1239. }
  1240.                              
  1241.